package server.core;

import java.util.Vector;

import server.client.Client;
import server.constants.core.IServer;
import server.output.Log;

/**
 * Der ServerDispatcher empfängt und verteilt Nachrichten
 * 
 * @author DarXun
 */
public class ServerDispatcher extends Thread {
        private Vector<String> messageQueue;
        private Vector<Client> clients;

        /**
         * Erzeugt einen neuen ServerDispatcher
         */
        public ServerDispatcher() {
                this.messageQueue = new Vector<String>();
                this.clients = new Vector<Client>();
        }

        /**
         * Fügt ein Client in die Liste ein
         * 
         * @param client
         */
        public synchronized void addClient(Client client) {
                this.clients.add(client);
                dispatchMessage(client, "CONNECTED");
                Log.writeLn(IServer.CLIENT_CONNECTED, client.getSocket().getInetAddress().getHostAddress());
        }

        /**
         * Entfernt einen Client aus der Liste
         * 
         * @param client
         *            Der zu entfernende Client
         */
        public synchronized void deleteClient(Client client) {
                int clientIndex = this.clients.indexOf(client);
                if (clientIndex != -1) {
                        this.clients.removeElementAt(clientIndex);
                }
                dispatchMessage(client, "DISCONNECTED");
                Log.writeLn(IServer.CLIENT_DISCONNECTED, client.getSocket().getInetAddress().getHostAddress());
        }

        /**
         * Fügt eine neue Nachricht hinzu
         * 
         * @param client
         *            Der SenderClient
         * @param message
         *            Die Nachricht
         */
        public synchronized void dispatchMessage(Client client, String message) {
//                Socket socket = client.getSocket();
//                String senderAddress = socket.getInetAddress().getHostAddress();
//                String senderPort = Integer.toString(socket.getPort());

                StringBuilder msgBuilder = new StringBuilder();
//                msgBuilder.append(senderAddress);
//                msgBuilder.append(":");
//                msgBuilder.append(senderPort);
//                msgBuilder.append(":");
                msgBuilder.append(message);

                this.messageQueue.add(msgBuilder.toString());
                notify();
        }

        /*
         * Gibt die aktuelle Nachricht zurück und entfernt diese aus der
         * messageQueue
         */
        private synchronized String getNextMessageFromQueue()
                        throws InterruptedException {
                while (this.messageQueue.size() == 0) {
                        wait();
                }

                String message = this.messageQueue.get(0);
                this.messageQueue.removeElementAt(0);

                return message;
        }
        
        /*
         * Sendet eine Nachricht an alle Clients
         */
        private synchronized void sendMessageToAllClients(String message) {
                for(Client client : this.clients) {
                        client.getClientSender().sendMessage(message);
                }
        }
        
        /*
         * Liest Nachrichten
         * (non-Javadoc)
         * @see java.lang.Thread#run()
         */
        @Override
        public void run() {
                try {
                        while (true) {
                                String message = getNextMessageFromQueue();
                                sendMessageToAllClients(message);
                        }
                } catch (InterruptedException ex) {
                        // Thread unterbrochen
                }
        }
}

